package cn.com.libertymutual.core.zxing;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

public class Zxing {

	private static Logger logger = LoggerFactory.getLogger(Zxing.class);

	public static void wirteImg(String content, String filePath, String fileName, String fileType, String logoFullName, String labels[], int width,
			int height) {
		try {
			String fullName = filePath + fileName;

			MultiFormatWriter multiFormatWriter = new MultiFormatWriter();

			Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
			// 设置UTF-8， 防止中文乱码
			hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
			// 设置二维码四周白色区域的大小
			hints.put(EncodeHintType.MARGIN, 1);
			// 设置二维码的容错性
			hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);

			// 画二维码，记得调用multiFormatWriter.encode()时最后要带上hints参数，不然上面设置无效
			BitMatrix bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, width, height, hints);

			// qrcFile用来存放生成的二维码图片（无logo，无文字）
			File qrcFile = new File(filePath, fileName);
			Path path = FileSystems.getDefault().getPath(filePath, fileName);

			// 开始画二维码
			MatrixToImageWriter.writeToPath(bitMatrix, fileType, path);
			// // 开始画二维码
			// MatrixToImageWriter.writeToPath(bitMatrix, fileType, qrcFile);

			if (StringUtils.isNotBlank(logoFullName)) {
				// logoFile用来存放带有logo的二维码图片（二维码+logo，无文字）
				File logoFile = new File(logoFullName);
				// 在二维码中加入图片
				LogoConfig logoConfig = new LogoConfig(); // LogoConfig中设置Logo的属性

				addLogo_QRCode(fileType, qrcFile, logoFile, logoConfig, fullName);
			}

			int font = 20; // 字体大小
			int fontStyle = 1; // 字体风格

			// 用来存放带有logo+文字的二维码图片
			String newImageWithText = fullName;
			// 带有logo的二维码图片
			String targetImage = fullName;

			// y开始的位置：图片高度-（图片高度-图片宽度）/2
			int startY = height - 32;
			// 在二维码下方添加文字（文字居中）
			pressText(fileType, labels[0], targetImage, newImageWithText, fontStyle, Color.black, font, width, height, startY);

			// y开始的位置：图片高度-（图片高度-图片宽度）/2
			startY = height - 10;
			// 在二维码下方添加文字（文字居中）
			pressText(fileType, labels[1], newImageWithText, targetImage, fontStyle, Color.black, font, width, height, startY);

		} catch (Exception e) {
			logger.info("输出二维码图片异常：", e);
		}
	}

	/**
	 * @为图片添加文字
	 * @param fileType 图片类型
	 * @param pressText 文字
	 * @param newImg    带文字的图片
	 * @param targetImg 需要添加文字的图片
	 * @param fontStyle 
	 * @param color
	 * @param fontSize
	 * @param width
	 * @param heigh
	 */
	public static void pressText(String fileType, String pressText, String newImg, String targetImg, int fontStyle, Color color, int fontSize,
			int width, int height, int startY) {
		try {
			File file = new File(targetImg);
			Image src = ImageIO.read(file);
			int imageW = src.getWidth(null);
			int imageH = src.getHeight(null);
			BufferedImage image = new BufferedImage(imageW, imageH, BufferedImage.TYPE_INT_RGB);
			Graphics2D g = image.createGraphics();

			g.drawImage(src, 0, 0, imageW, imageH, null);
			g.setColor(color);
			Font font = new Font(null, fontStyle, fontSize);
			g.setFont(font);
			g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

			// 计算文字长度，计算居中的x点坐标
			FontMetrics fm = g.getFontMetrics(font);
			int textWidth = fm.stringWidth(pressText);

			// 计算文字开始的位置
			int widthX = (width - textWidth) / 2;

			g.drawString(pressText, widthX, startY);
			g.dispose();

			FileOutputStream out = new FileOutputStream(newImg);
			ImageIO.write(image, fileType, out);

			out.close();
		} catch (Exception e) {
			logger.info("为图片添加文字异常：", e);
		}
	}

	/**
	 * 给二维码图片添加Logo
	 * @param fileType 图片类型
	 * @param qrPic
	 * @param logoPic
	 */
	public static void addLogo_QRCode(String fileType, File qrPic, File logoPic, LogoConfig logoConfig, String fullName) {
		try {
			if (!qrPic.isFile()) {
				logger.info("qrPic file not find !");
			}
			if (!logoPic.isFile()) {
				logger.info("logoPic file not find !");
			}

			/**
			 * 读取二维码图片，并构建绘图对象
			 */
			BufferedImage image = ImageIO.read(qrPic);
			Graphics2D g = image.createGraphics();

			/**
			 * 读取Logo图片
			 */
			BufferedImage logo = ImageIO.read(logoPic);

			int widthLogo = image.getWidth() / logoConfig.getLogoPart();
			// int heightLogo = image.getHeight()/logoConfig.getLogoPart();
			int heightLogo = image.getWidth() / logoConfig.getLogoPart(); // 保持二维码是正方形的

			// 计算图片放置位置
			int x = (image.getWidth() - widthLogo) / 2;
			int y = (image.getHeight() - heightLogo) / 2;

			// 开始绘制图片
			g.drawImage(logo, x, y, widthLogo, heightLogo, null);
			g.drawRoundRect(x, y, widthLogo, heightLogo, 10, 10);
			g.setStroke(new BasicStroke(logoConfig.getBorder()));
			g.setColor(logoConfig.getBorderColor());
			g.drawRect(x, y, widthLogo, heightLogo);

			g.dispose();

			ImageIO.write(image, fileType, new File(fullName));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		download("http://ui.51bi.com/opt/siteimg/images/fanbei0923/Mid_07.jpg", "51bi.jpg", "D:\\image\\");
		// download("http://www.hao123.com/", "nidi.html", "D:\\image\\");
	}

	/**Remarks: 将url突破保存到目录<br>
	 * Version：1.0<br>
	 * Author：AoYi<br>
	 * DateTime：2018年1月29日上午9:48:11<br>
	 * Project：liberty_sale_plat<br>
	 * @param urlString 地址
	 * @param filename 文件名称
	 * @param savePath 保存路径
	 * @throws Exception
	 */
	public static void download(String urlString, String filename, String savePath) throws Exception {
		// 构造URL
		URL url = new URL(urlString);
		// 打开连接
		URLConnection con = url.openConnection();
		// 设置请求超时为5s
		con.setConnectTimeout(5 * 1000);
		// 输入流
		InputStream is = con.getInputStream();

		// 1K的数据缓冲
		byte[] bs = new byte[1024];
		// 读取到的数据长度
		int len;
		// 输出的文件流
		File sf = new File(savePath);
		if (!sf.exists()) {
			sf.mkdirs();
		}
		OutputStream os = new FileOutputStream(savePath + filename);
		// 开始读取
		while ((len = is.read(bs)) != -1) {
			os.write(bs, 0, len);
		}
		// 完毕，关闭所有链接
		os.close();
		is.close();
	}

	// 递归删除文件夹
	public static void deleteFile(File file) {
		if (file.exists()) {// 判断文件是否存在
			if (file.isFile()) {// 判断是否是文件
				file.delete();// 删除文件
			} else if (file.isDirectory()) {// 否则如果它是一个目录
				File[] files = file.listFiles();// 声明目录下所有的文件 files[];
				if( files != null ) {
					for (int i = 0; i < files.length; i++) {// 遍历目录下所有的文件
						Zxing.deleteFile(files[i]);// 把每个文件用这个方法进行迭代
					}
				}
				file.delete();// 删除文件夹
			}
		} else {
			logger.info("所删除的文件或文件夹不存在");
		}
	}

}
